package com.pfzy.ui.activity.notification

import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Intent
import android.graphics.BitmapFactory
import android.graphics.Color
import android.os.Build
import android.os.Looper
import android.provider.Settings
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.NotificationManagerCompat
import com.pfzy.ui.ForegroundActivityManager
import com.pfzy.ui.R
import java.util.concurrent.atomic.AtomicInteger

/**
 * 通知的管理类
 * example:
 *     //发系统通知
 *    NotificationControlManager.getInstance()?.notify("文件上传完成", "文件上传完成,请点击查看详情")
 *    //发应用内通知
 *     NotificationControlManager.getInstance()?.showNotificationDialog("文件上传完成","文件上传完成,请点击查看详情",
 *           object : NotificationControlManager.OnNotificationCallback {
 *                override fun onCallback() {
 *                   Toast.makeText(this@MainActivity, "被点击了", Toast.LENGTH_SHORT).show()
 *                 }
 *    })
 */
class NotificationControlManager {
    private var autoIncreament = AtomicInteger(1001)
    private var contentMap = mutableListOf<NotificationInfo>()
    private var dialogList = mutableListOf<NotificationDialog>()

    companion object {
        const val channelId = "app"
        const val description = "my application"

        @Volatile
        private var sInstance: NotificationControlManager? = null

        @JvmStatic
        fun getInstance(): NotificationControlManager {
            if (sInstance == null) {
                synchronized(NotificationControlManager::class.java) {
                    if (sInstance == null) {
                        sInstance = NotificationControlManager()
                    }
                }
            }
            return sInstance!!
        }
    }


    /**
     * 是否打开通知
     */
    fun isOpenNotification(): Boolean {
        val notificationManager: NotificationManagerCompat =
            NotificationManagerCompat.from(
                ForegroundActivityManager.getInstance()?.getCurrentActivity()!!
            )
        return notificationManager.areNotificationsEnabled()
    }


    /**
     * 跳转到系统设置页面去打开通知，注意在这之前应该有个Dialog提醒用户
     */
    fun openNotificationInSys() {
        val context = ForegroundActivityManager.getInstance()?.getCurrentActivity()!!
        val intent: Intent = Intent()
        try {
            intent.action = Settings.ACTION_APP_NOTIFICATION_SETTINGS

            //8.0及以后版本使用这两个extra.  >=API 26
            intent.putExtra(Settings.EXTRA_APP_PACKAGE, context.packageName)
            intent.putExtra(Settings.EXTRA_CHANNEL_ID, context.applicationInfo.uid)

            //5.0-7.1 使用这两个extra.  <= API 25, >=API 21
            intent.putExtra("app_package", context.packageName)
            intent.putExtra("app_uid", context.applicationInfo.uid)

            context.startActivity(intent)
        } catch (e: Exception) {
            e.printStackTrace()

            //其他低版本或者异常情况，走该节点。进入APP设置界面
            intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
            intent.putExtra("package", context.packageName)

            //val uri = Uri.fromParts("package", packageName, null)
            //intent.data = uri
            context.startActivity(intent)
        }
    }

    /**
     * 发通知
     * @param title 标题
     * @param content 内容
     * @param cls 通知点击后跳转的Activity,默认为null跳转到MainActivity
     */
    fun notify(title: String, content: String, cls: Class<*>) {
        val context = ForegroundActivityManager.getInstance()?.getCurrentActivity()!!
        val notificationManager = context.getSystemService(AppCompatActivity.NOTIFICATION_SERVICE) as NotificationManager
        val builder: Notification.Builder
        val intent = Intent(context, cls)
        val pendingIntent: PendingIntent? = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_ONE_SHOT)
//        val pendingIntent: PendingIntent? = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {// 安卓12
//            PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE)
//        } else {
//            PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_ONE_SHOT)
//        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val notificationChannel =
                NotificationChannel(channelId, description, NotificationManager.IMPORTANCE_HIGH)
            notificationChannel.enableLights(true);
            notificationChannel.lightColor = Color.RED;
            notificationChannel.enableVibration(true);
            notificationChannel.vibrationPattern =
                longArrayOf(100, 200, 300, 400, 500, 400, 300, 200, 400)
            notificationManager.createNotificationChannel(notificationChannel)
            builder = Notification.Builder(context, channelId)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentIntent(pendingIntent)
                .setContentTitle(title)
                .setContentText(content)
        } else {
            builder = Notification.Builder(context)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setLargeIcon(
                    BitmapFactory.decodeResource(
                        context.resources,
                        R.mipmap.ic_launcher
                    )
                )
                .setContentIntent(pendingIntent)
                .setContentTitle(title)
                .setContentText(content)

        }
        notificationManager.notify(autoIncreament.incrementAndGet(), builder.build())
    }


    /**
     * 显示应用内通知的Dialog,需要自己处理点击事件。listener默认为null,不处理也可以。dialog会在3000毫秒后自动消失
     * @param title 标题
     * @param content 内容
     * @param filterActivityByClassNameList 过滤哪些类不显示Dialog
     * @param listener 点击的回调
     */
    fun showNotificationDialog(
        title: String,
        content: String,
        filterActivityByClassNameList: MutableList<String>? = null,
        listener: OnNotificationCallback? = null
    ) {
        val currentActivity = ForegroundActivityManager.getInstance()?.getCurrentActivity()!!
        //判断是否需要过滤页面不显示Dialog
        filterActivityByClassNameList?.forEach {
            val className = currentActivity.javaClass.simpleName
            if (className == it) {
                return
            }
        }

        val isActive = ForegroundActivityManager.getInstance()?.getActive() ?: false
        if (isActive) {  //Active状态
            val dialog = NotificationDialog(currentActivity, title, content)
            dialogList.add(dialog)
            if (Thread.currentThread() != Looper.getMainLooper().thread) {   //子线程
                currentActivity.runOnUiThread {
                    dialog.showDialogAutoDismiss()
                    setDialogClick(dialog, listener)
                }
            } else {
                dialog.showDialogAutoDismiss()
                setDialogClick(dialog, listener)
            }
        } else {  //如果当前Activity非Active状态则把要显示的内容存储到集合中
            //存到集合中
            contentMap.add(NotificationInfo(title, content))
        }
    }


    /**
     * 显示应用内通知的Dialog,需要自己处理点击事件。listener默认为null,不处理也可以。dialog会在3000毫秒后自动消失
     * @param title 标题
     * @param content 内容
     * @param activity 需要传入Activity(主要碰到多进程的问题)
     * @param listener 点击的回调
     */
    fun showNotificationDialog(
        title: String,
        content: String,
        activity: AppCompatActivity,
        listener: OnNotificationCallback? = null
    ) {
        val dialog = NotificationDialog(activity, title, content)
        dialogList.add(dialog)
        if (Thread.currentThread() != Looper.getMainLooper().thread) {   //子线程
            activity.runOnUiThread {
                dialog.showDialogAutoDismiss()
                setDialogClick(dialog, listener)
            }
        } else {
            dialog.showDialogAutoDismiss()
            setDialogClick(dialog, listener)
        }
    }


    /**
     * 显示应用内通知的Dialog,需要自己处理点击事件。listener默认为null,不处理也可以。dialog会在3000毫秒后自动消失
     * @param title 标题
     * @param content 内容
     * @param activity 需要传入Activity(主要碰到多进程的问题)
     * @param listener 点击的回调
     */
    fun showNotificationDialogWithNotLifecycle(
        title: String,
        content: String,
        activity: AppCompatActivity,
        listener: OnNotificationCallback? = null
    ) {
        val dialog = NotificationDialog(activity, title, content)
        dialogList.add(dialog)
        if (Thread.currentThread() != Looper.getMainLooper().thread) {   //子线程
            activity.runOnUiThread {
                dialog.showDialogAutoDismiss()
                setDialogClick(dialog, listener)
            }
        } else {
            dialog.showDialogAutoDismiss()
            setDialogClick(dialog, listener)
        }
    }


    /**
     * set dialog click
     */
    private fun setDialogClick(
        dialog: NotificationDialog?,
        listener: OnNotificationCallback?
    ) {
        if (listener != null) {
            dialog?.setOnNotificationClickListener(object :
                NotificationDialog.OnNotificationClick {
                override fun onClick() = listener.onCallback()
            })
        }
    }

    /**
     * 显示没有显示过的Dialog
     */
    fun showDialogNeverVisible() {
        if (contentMap.isNotEmpty()) {
            val iterator = contentMap.iterator()
            while (iterator.hasNext()) {
                val info = iterator.next()
                val currentActivity =
                    ForegroundActivityManager.getInstance()?.getCurrentActivity()!!
                val dialog = NotificationDialog(currentActivity, info.title, info.content)
                dialogList.add(dialog)
                if (Thread.currentThread() != Looper.getMainLooper().thread) {   //子线程
                    currentActivity.runOnUiThread {
                        dialog.showDialogAutoDismiss()
                        setDialogClick(dialog, null)   //这里需要根据场景完善点击事件
                        iterator.remove()
                    }
                } else {
                    dialog.showDialogAutoDismiss()
                    setDialogClick(dialog, null)   //这里需要根据场景完善点击事件
                    iterator.remove()
                }
            }
        }
    }

    /**
     * dismiss Dialog
     */
    fun dismissDialogWithLifecycle() {
        if (dialogList.size > 0) {
            val iterator = dialogList.iterator()
            while (iterator.hasNext()) {
                val dialog = iterator.next()
                if (dialog != null && dialog.isShowing) {
                    dialog.dismiss()
                }
                iterator.remove()
            }
        }
    }

    interface OnNotificationCallback {
        fun onCallback()
    }
}
